;; Idea:
;; Write (thunk (+ a b)) instead of (lambda () (+ a b)).

(import
 (except (rnrs base) let-values)
 (only (guile)
       lambda* λ))


;; (define-curried blub
;;   (lambda (arg1 arg2 arg3)
;;     expr1
;;     expr2))

;; -->

;; (define blub
;;   (lambda (arg1)
;;     (lambda (arg2)
;;       (lambda (arg3)
;;         expr1
;;         expr2))))

(define-syntax curried-lambda
  (syntax-rules ()
    [(_ (arg args* ...) expr* ...)
     ;; Take one argument and wrap in a lambda.
     (lambda (arg)
       ;; Do the macro for the other arguments.
       (curried-lambda (args* ...) expr* ...))]
    ;; If there are no more arguments, output the
    ;; expressions of the body in the previous inner-most
    ;; lambda.
    [(_ () expr* ...)
     ((lambda () expr* ...))]))


(define-syntax define-curried
  (syntax-rules ()
    ;; Case of 1 or more arguments.
    [(_ function-name
        (lambda (arg args* ...)
          expr* ...))
     (define function-name
       (lambda (arg)
         ;; Create nested lambdas.
         (curried-lambda (args* ...) expr* ...)))]
    ;; Case of no function arguments.
    [(_ function-name (lambda () expr* ...))
     (define function-name
       (lambda ()
         expr* ...))]))


;; But for convenient calling of the function, one might
;; need a syntax as well.

;; (curry-call (foobar arg1 arg2 arg3))

;; OR perhaps:

;; (curry-call foobar arg1 arg2 arg3)


(define-syntax curry-call
  (syntax-rules ()
    [(_ function-name ???)
     #|TODO|#]))
